package com.tl.ip_location_relation_v4.controller;

import java.io.File;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;

import com.tl.ip_location_relation_v4.entity.Ip;
import com.tl.ip_location_relation_v4.service.IpSearchV3;
import com.tl.ip_location_relation_v4.utils.CacheUtils;
import com.tl.ip_location_relation_v4.utils.ConfigUtil;
import com.tl.ip_location_relation_v4.utils.DBPoolUtils;
import com.tl.ip_location_relation_v4.utils.IpLoadToDB;
import com.tl.ip_location_relation_v4.utils.IpUtil;
import com.tl.ip_location_relation_v4.utils.JDBCUtils;

/**
 * 
 * @author Antg
 * @date 2021年7月13日
 * @Description V3: <br>
 *              对V2进行了如下优化: <br>
 *              1.将数据加载到了mysql数据库中<br>
 *              2.给数据库表加入了索引,加快了查询速度<br>
 *              3.使用到了数据库连接池技术
 */
public class ControllerV3 {
	private static String ipFile = ConfigUtil.getConfig("file");
	private static String charSet = ConfigUtil.getConfig("charset");
	private static String cachePath = ConfigUtil.getConfig("objcache");
	private static File objcache = new File(cachePath);
	private static String ip = "";
	private static Scanner scanner = new Scanner(System.in);
	private static List<Ip> ipList = null;
	private static long beginTime = 0L;
	private static String db_table = ConfigUtil.getConfig("db_table");

	public static void run() {
		Connection conn = null;
		try {
			conn = DBPoolUtils.getInstance().getBasicDataSource()
					.getConnection();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		boolean ifEmptyTable = JDBCUtils.ifEmptyTable(conn, db_table);
		System.out.println("==========欢迎进入v3版本==========");
		// 如果数据库中没有数据,那么首先加载文件数据,否则直接进行查询
		if (ifEmptyTable) {
			if (!objcache.exists()) {
				// 数据加载
				beginTime = System.currentTimeMillis();
				ipList = IpUtil.loadDataAndSwitchV2(ipFile, charSet);
				System.out.println("数据加载用时--->"
						+ (System.currentTimeMillis() - beginTime) + "毫秒");
				// 数据排序
				beginTime = System.currentTimeMillis();
				Collections.sort(ipList);
				System.out.println("数据排序用时--->"
						+ (System.currentTimeMillis() - beginTime) + "毫秒");
				// 数据缓存
				beginTime = System.currentTimeMillis();
				CacheUtils.cacheObj(ipList, cachePath);
				System.out.println("数据缓存用时--->"
						+ (System.currentTimeMillis() - beginTime) + "毫秒");

			} else {
				beginTime = System.currentTimeMillis();
				ipList = (List<Ip>) CacheUtils.getObjCache(cachePath);
				System.out.println("缓存数据读取用时--->"
						+ (System.currentTimeMillis() - beginTime) + "毫秒");
			}
			// 加载数据到数据库
			beginTime = System.currentTimeMillis();
			IpLoadToDB.load(ipList);// 批量插入
			System.out.println("数据插入到数据库用时--->"
					+ (System.currentTimeMillis() - beginTime) + "毫秒");
		}
		// 数据查询
		System.out.println("============功能列表============");
		System.out.println("1 : 查询ip所属区域");
		System.out.println("2 : 清空数据");
		System.out.println("3 : 批量加载数据到数据库");
		System.out.println("4 : 一条一条加载数据到数据库");
		System.out.println("0 : 退出系统");
		System.out.println("==============================");
		while (true) {
			System.out.print("请选择操作:");
			String op = scanner.next();
			if (!op.equals("0") && !op.equals("1") && !op.equals("2")
					&& !op.equals("3") && !op.equals("4")) {
				System.out.println("输入有误,请重新输入");
				continue;
			}
			if (!op.equals("0")) {
				ifEmptyTable = JDBCUtils.ifEmptyTable(conn, db_table);
			}

			switch (op) {
			case "1":
				System.out.print("请输入要查询的ip地址:");
				ip = scanner.next();
				if (!IpUtil.validateIp(ip)) {
					System.out.println("ip地址格式不正确,请检查");
					return;
				}
				beginTime = System.currentTimeMillis();
				String result = IpSearchV3.search(ip);

				if (result != null) {
					System.out.print(result + "   ");
				} else {
					System.out.println("查询结果不存在");
				}
				System.out.println("查询用时--->"
						+ (System.currentTimeMillis() - beginTime) + "毫秒");
				break;
			case "2":
				// 如果是空表,则不需要清空
				if (ifEmptyTable) {
					System.out.println("数据表已经为空,不需要清空");
					break;
				}
				// 清空数据
				JDBCUtils.clearTable(conn, db_table);
				System.out.println("表已清空");
				break;
			case "3":
				// 如果不是是空表,则不需要插入数据
				if (!ifEmptyTable) {
					System.out.println("数据已经存在,如需要重新插入,请先清空表");
					break;
				}

				// 从新加载数据
				if (ipList == null) {
					beginTime = System.currentTimeMillis();
					ipList = (List<Ip>) CacheUtils.getObjCache(cachePath);
					System.out.println("缓存数据读取用时--->"
							+ (System.currentTimeMillis() - beginTime) + "毫秒");
				}
				// 批量插入到数据库中
				beginTime = System.currentTimeMillis();
				IpLoadToDB.load(ipList);
				System.out.println("批量插入到数据库用时--->"
						+ (System.currentTimeMillis() - beginTime) + "毫秒");
				break;
			case "4":
				// 如果不是是空表,则不需要插入数据
				if (!ifEmptyTable) {
					System.out.println("数据已经存在,如需要重新插入,请先清空表");
					break;
				}
				// 从新加载数据
				if (ipList == null) {
					beginTime = System.currentTimeMillis();
					ipList = (List<Ip>) CacheUtils.getObjCache(cachePath);
					System.out.println("缓存数据读取用时--->"
							+ (System.currentTimeMillis() - beginTime) + "毫秒");
				}
				// 一条一条插入到数据库中
				beginTime = System.currentTimeMillis();
				IpLoadToDB.loadOneByOne(ipList);
				System.out.println("一条一条插入到数据库用时--->"
						+ (System.currentTimeMillis() - beginTime) + "毫秒");
				break;
			case "0":
				System.out.println("系统退出!");
				return;
			}
		}

	}
}
